package com.xxg.fileshand.base

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.ToastUtils
import com.xxg.fileshand.net.NetWorkException
import com.xxg.fileshand.net.RetrofitManager
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.launch
import org.json.JSONException
import retrofit2.HttpException
import java.io.IOException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.text.ParseException

open class BaseViewModel : ViewModel() {

    protected fun launch(block: suspend () -> Unit, error: (e: Exception) -> Unit) {
        viewModelScope.launch(CoroutineExceptionHandler { _, e -> error(e) }) {
            try {
                block()
            } catch (e: Exception) {
                filterException(e, error)
            }
        }
    }

    private fun <T> filterException(e: Exception, error: (e: Exception) -> T) {
        val errorMsg: String
        when (e) {
            is NetWorkException -> {//接口通信正常 自定义错误
                errorMsg = e.message ?: "" + " , code:" + e.code
                error(Exception(errorMsg))
            }
            is UnknownHostException -> {
                errorMsg = "连接服务器失败,未知host"
                error(Exception(errorMsg))
            }
            is ConnectException -> {
                errorMsg = "连接服务器失败，请检查网络是否可用"
                error(Exception(errorMsg))
            }
            is SocketTimeoutException -> {
                errorMsg = "请求网络超时,请稍后再试"
                error(Exception(errorMsg))
            }
            is ParseException -> {
                errorMsg = "数据解析错误"
                error(Exception(errorMsg))
            }
            is JSONException -> {
                errorMsg = "数据解析错误"
                error(Exception(errorMsg))
            }
            is HttpException -> {
                errorMsg = convertStatusCode(e)
                error(Exception(errorMsg))
            }
            is IOException -> {
                errorMsg = e.message ?: ""
                error(e)
            }
            else -> {
                errorMsg = e.message ?: ""
                error(e)
            }
        }
        ToastUtils.showShort(errorMsg)
    }

    private fun convertStatusCode(httpException: HttpException): String {
        val msg: String = when {
            httpException.code() in 500..599 -> {
                "服务器处理请求出错:${httpException.code()}"
            }
            httpException.code() in 400..499 -> {
                "服务器无法处理请求:${httpException.code()}"
            }
            httpException.code() in 300..399 -> {
                "请求被重定向到其他页面:${httpException.code()}"
            }
            else -> {
                httpException.message() + ":" + httpException.code()
            }
        }
        return msg
    }

    /**
     * 网络请求接口创建
     */
    fun <T> createApi(cls: Class<T>): T {
        return RetrofitManager.build().create(cls)
    }
}